<template>
  <!-- 文件上传组件
       :limit 限制上传的个数
       :multiple 是否可以一次选择多个图片
       action属性用于指定文件上传地址, 这里要写 #, 占个位置
       如果直接写地址，就是由element-ui帮你发post请求, 有一定的局限性，我们自己请求

       :on-exceed 选择的文件个数，超出limit触发
       :on-preview 点击预览按钮，触发该函数
       :on-remove 文件列表的某个文件被移除时，触发该函数
       :on-change 新增文件，上传成功，上传失败触发 => 让data中的 fileList 和 视图的数据统一
  -->
  <div>
    <el-upload
      :limit="limit"
      :multiple="isMultiple"
      action="#"
      list-type="picture-card"
      :file-list="fileList"
      :on-exceed="handleExceed"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-change="handleChange"
      :http-request="upload"
      :before-upload="beforeUpload"
      :class="{ disabled: fileComputed }"
    >
      <!-- +号图标 -->
      <i class="el-icon-plus" />
    </el-upload>

    <el-dialog
      top="5vh"
      title="预览图片"
      width="500px"
      :visible="dialogVisible"
      @close="closeDialog"
    >
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>

<script>
import COS from 'cos-js-sdk-v5' // 导入腾讯云的包(sdk)  注意：下载

const cos = new COS({
  SecretId: 'AKIDlbRs3lGwQeaIMDnq0vuooY3HETTDKSGo', // 身份识别ID
  SecretKey: 'ixEQ4TbpqiEg4C31FG2mV3OTO7g5JLTL' // 身份秘钥
})

export default {
  props: {
    limit: {
      default: 1,
      type: Number
    },
    isMultiple: {
      default: false,
      type: Boolean
    }
  },
  data() {
    return {
      fileList: [],
      dialogVisible: false,
      dialogImageUrl: ''
    }
  },
  computed: {
    // 标记，文件是否上传满 限制的文件数量
    fileComputed() {
      return this.fileList.length >= this.limit
    },
    isAllSuccess() {
      return this.fileList.every(item => item.status === 'success')
    }
  },
  methods: {
    handleExceed() {
      // 注意：因为如果超出了，又选了一个文件，到底如何处理，应该我们说了算，而不是定死不让传
      // console.log('将来: 如果上传选择文件了, 超出了limit, 就会触发执行这个函数')
      this.$message.error('文件上传已达最大个数哦')
    },
    handlePreview(file) {
      // console.log('预览了', file)
      // 单页内跳转          this.$router.push
      // 跳到单页以外的页面去 location.href = xxx
      // location.href = file.url

      this.dialogVisible = true // 显示对话框
      this.dialogImageUrl = file.url // 将预览的图片地址赋值给变量
    },
    // fileList      页面中看到的fileList数据源 （被删了一项）
    // this.fileList 自己的data中的数据源       （还没同步）
    handleRemove(file, fileList) {
      // console.log(file, fileList)
      // this.fileList = [...fileList]

      // 根据 file.uid 去 this.fileList 删除对应的这一项, 保留非该 uid 的所有项
      this.fileList = this.fileList.filter(item => item.uid !== file.uid)
    },
    closeDialog() {
      this.dialogVisible = false
    },
    // 配置上传前的校验, 只要通过校验, 才能进行上传
    beforeUpload(file) {
      // 1. 限制文件类型 file.type
      const types = ['image/jpeg', 'image/gif', 'image/bmp', 'image/png', 'image/svg+xml']
      if (!types.includes(file.type)) {
        this.$message.error('上传的图片格式, 必须是jpg, gif, bmp, png, svg的格式!')
        return false
      }
      // 2. 限制文件大小 file.size
      if (file.size / 1024 / 1024 >= 5) {
        this.$message.error('上传头像过大, 超过了5M, 必须5M以内')
        return false
      }
      return true
    },
    upload(params) {
      // console.log('我要开始上传了', params.file)
      // 1. 利用axios语法，上传
      // const formData = new FormData()
      // formData.append('file', params.file)
      // axios.post(url, formData)
      // 2. 利用腾讯云语法，上传
      if (params.file) {
        // dataFile 是 fileList 数据层的对象，其中有 status 等状态
        const dataFile = this.fileList.find(item => item.uid === params.file.uid)
        cos.putObject({
          Bucket: 'shuaipeng-1256203106', // 存储桶名字
          Region: 'ap-shanghai', // 存储桶所在地域
          Key: params.file.name, // 上传后存储的文件名
          Body: params.file, // 上传的文件对象
          // 监听上传的进度
          onProgress: (progressData) => {
            // 上传中，将status改成uploading，实时的根据上传的进度，设置percentage
            dataFile.status = 'uploading'
            dataFile.percentage = Math.ceil(progressData.percent * 100)
          }
        }, (err, data) => {
          if (err) {
            this.$message.error('上传失败')
            return
          }
          setTimeout(() => {
            // 成功，将status改成成功，url地址更新一下
            dataFile.status = 'success'
            dataFile.url = 'https://' + data.Location
          }, 500)
        })
      }
    },
    handleChange(file, fileList) {
      // 本身2张图，加了1张，fileList直接变成了3张，但是this.fileList 2张（data中的）
      this.fileList = [...fileList]
    },
    init(fileList) {
      this.fileList = fileList
    }
  }
}
</script>

<style scoped lang="scss">
.disabled {
  ::v-deep {
    .el-upload--picture-card {
      display: none
    }
  }
}
</style>

